package com.mojavelinux.open18;

import java.util.Iterator;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

import org.jboss.seam.core.Messages;

/**
 * @see http://www.oracle.com/technology/pub/articles/masterj2ee/j2ee_wk7.html
 */
public class MessageDecoratorPhaseListener implements PhaseListener {

	private static final long serialVersionUID = 1L;

	public PhaseId getPhaseId() {
		return PhaseId.RENDER_RESPONSE;
	}

	@SuppressWarnings( "unchecked" )
	public void beforePhase( PhaseEvent event ) {
		FacesContext facesContext = event.getFacesContext();
		Map<String, String> messages = Messages.instance();
		UIViewRoot viewRoot = facesContext.getViewRoot();
		Iterator<String> idIter = facesContext.getClientIdsWithMessages();
		while ( idIter.hasNext() ) {
			String clientId = idIter.next();

			if ( clientId == null ) {
				continue;
			}

			UIComponent component = viewRoot.findComponent( clientId );
			String localId = null;
			if ( !( component instanceof UIInput ) ) {
				// findComponent cannot locate UIInput components inside a UIData container
				if ( clientId.matches( ".*:[0-9]+:.*" ) ) {
					localId = clientId.substring( clientId.lastIndexOf( ':' ) + 1 );
				}
			}
			else {
				localId = component.getId();
			}

			if ( localId == null ) {
				continue;
			}

			Iterator<FacesMessage> messageIter = facesContext.getMessages( clientId );
			while ( messageIter.hasNext() ) {
				FacesMessage message = messageIter.next();
				String fieldName = localId;
				String key = new StringBuffer( 25 ).append( "field_" ).append( localId ).toString();
				if ( messages.containsKey( key ) ) {
					fieldName = messages.get( key );
				}
				else {
					fieldName = new StringBuffer( 25 ).append( fieldName.substring( 0, 1 ).toUpperCase() ).append(
						fieldName.substring( 1 ) ).toString();
				}

				message.setSummary( new StringBuffer( 50 ).append( fieldName ).append( " " ).append(
					message.getSummary() ).toString() );
			}
		}
	}

	public void afterPhase( PhaseEvent event ) {
	// not interested
	}

}
